package com.ming.websocket.server;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

@Component
@Slf4j
@ServerEndpoint("/api/test/pushMsg/{userId}")// 前端通过这个URI和后端交互，建立连接
public class WebSocketServer {
    // 在线连接数
    private static int onlineCount = 0;
    // 存放每个客户端对应的socket对象
    private static ConcurrentHashMap<String,WebSocketServer> webSocketMap = new ConcurrentHashMap<>();
    // 与客户端的连接会话,以此发送数据
    private Session session;
    private String userId = null;

    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId){
        this.session = session;
        this.userId = userId;
        if(webSocketMap.containsKey(userId)){
            webSocketMap.remove(userId);
            webSocketMap.put(userId,this);
        }else{
            webSocketMap.put(userId,this);
            addOnlineCount();
        }
        log.info("用户:{}连接成功,当前在线人数:{}",userId,getOnlineCount());
        sendMessage("连接成功");
    }
    @OnClose
    public void onClose(){
        if(webSocketMap.containsKey(userId)){
            webSocketMap.remove(userId);
            subOnlineCount();
        }
        log.info("用户:{}退出连接,当前在线人数:{}",userId,getOnlineCount());
    }
    // 收到客户端消息后调用的方法
    @OnMessage
    public void onMessage(String message,Session session){
        log.info("用户:{},报文:{}",userId,message);
        // 群发消息 | 保存数据库
        if(message!=null){
            JSONObject jsonObject = (JSONObject) JSON.parse(message);
            jsonObject.put("fromObject",this.userId);
            String toUserId = jsonObject.getString("toUserId");
            // 传递给对应的userId
            if(toUserId != null && webSocketMap.containsKey(toUserId)){
                webSocketMap.get(toUserId).sendMessage(message);
            }else{
                log.error("请求的:{}不存在",toUserId);
            }
        }
    }
    @OnError
    public void onError(Session session,Throwable error){
        log.error("用户错误:{},原因:{}",this.userId,error.getMessage());
        error.printStackTrace();
    }
    // 服务器主动推送
    public void sendMessage(String message){
        try {
            this.session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    // 发送自定义消息
    public static void sendInfo(String message,String userId){
        log.info("发送消息到:{},报文:{}",userId,message);
        if(userId!=null && webSocketMap.containsKey(userId)){
            webSocketMap.get(userId).sendMessage(message);
        }else{
            log.error("用户:{} 不在线",userId);
        }
    }

    // 当前在线人数
    public static synchronized int getOnlineCount(){
        return onlineCount;
    }
    // 在线人数+1
    public static synchronized void addOnlineCount(){
        WebSocketServer.onlineCount++;
    }
    // 在线人数-1
    public static synchronized void subOnlineCount(){
        WebSocketServer.onlineCount--;
    }

    
}
